Day 09 完成了第一版 Memory,讓 AI 可以從對話中抽取值得記住的資訊,並存進資料庫。
例如:
使用者:
「我平常晚上喜歡出去散步。」
↓
Memory Extraction
↓
{
"type": "preference",
"content": "晚上喜歡散步"
}
↓
Memory Store
但把 Memory 存進去,其實只完成了一半。
隨著對話越來越多,未來可能累積幾百甚至幾千筆 Memory。如果每次對話都把全部 Memory 丟給 LLM,不只 Context 會越來越長,也可能讓不相關的資訊影響回答。
所以今天要解決的是:
AI 已經記得很多事情,但這一輪到底該想起哪一件?
Memory Retrieval 就是在新的對話開始時,從過去儲存的 Memory 中,找出和目前對話最相關的內容。
例如資料庫裡有:
晚上喜歡散步
早餐習慣喝豆漿
喜歡看棒球
上週提過睡不好
今天使用者說:
「今天晚上不知道要做什麼。」
這時候真正有用的 Memory 應該是:
「晚上喜歡散步」
而不是把其他所有資訊一起交給 LLM。
最簡單的方法是使用關鍵字搜尋。
例如使用者說「散步」,就去尋找包含「散步」的 Memory。
但實際對話不一定會使用完全相同的文字。
例如:
Memory:
「晚上喜歡散步」
User:
「等等想出去走走。」
雖然「散步」和「走走」使用的文字不同,但兩句話的意思其實很接近。
因此今天加入 Semantic Search。
Semantic Search 不只是比較有沒有相同的關鍵字,而是比較兩段文字在「語意」上是否接近。
要進行 Semantic Search,首先需要把文字轉成 Embedding。
可以簡單理解成:
文字
↓
Embedding Model
↓
Vector
Embedding Model 會把一段文字轉成一串數字。
語意越接近的內容,在向量空間中的位置通常也會越接近,因此就可以利用向量之間的相似度找到相關 Memory。
當 Memory 越來越多,就需要一個地方保存這些 Embedding。
Vector Database 主要負責儲存向量,並在新的 Query 進來時,快速搜尋最相似的資料。
因此新增 Memory 時,可以同時儲存:
Memory
+
Embedding
新的對話進來後,再把目前的內容轉成 Embedding,搜尋最相關的 Memory。
目前的流程變成:
使用者:
「今天晚上不知道要做什麼。」
↓
Embedding
↓
Vector Search
↓
找到相關 Memory:
「使用者晚上喜歡散步」
↓
加入 LLM Context
↓
LLM Response
原本沒有 Memory 時,AI 可能只會回答:
「可以看看電影、聽音樂或出去走走。」
加入 Retrieval 找到的 Memory 後,就可以回答:
「你之前提過晚上喜歡散步,
如果今天天氣不錯,可以出去走走。」
這也是 Memory 開始真正影響 AI Companion 回答的地方。
目前也先把 Memory 分成兩個方向:
General Memory
├─ Preference
├─ Habit
└─ Personal Information
Health Memory
├─ Sleep
├─ Diet
├─ Activity
├─ Medication
└─ Symptom
一般聊天可以優先搜尋 General Memory;如果對話和身體狀況、睡眠、飲食或用藥有關,再搜尋 Health Memory。
這樣就不用每次把所有記憶一起丟進 Context,也能減少不相關資訊影響回答。
今天先完成第一版 Memory Retrieval,讓 AI 不只是把事情「記住」,也開始能在新的對話中找回相關的 Memory。
但接下來還有一個問題:
如果使用者之後說了不同的事情,原本的 Memory 該怎麼辦?
Day 11 會繼續處理 Memory 的更新、衝突與遺忘。